package com.fcat.base.smartapi.lib;

import java.math.BigInteger;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Random;

public class BaseToken {

    private WorkType workType;

    public String StrToken;

    public String styleToken;

    //ORIGINAL LINE: public byte[] ByteTokens = new byte[9];
    public byte[] ByteTokens = new byte[9];

    //ORIGINAL LINE: protected byte[] ByteKey = new byte[8];
    protected byte[] ByteKey = new byte[8];

    // Token: 0x0400000A RID: 10
    protected boolean IsKey;

    //ORIGINAL LINE: public ushort TCRC;
    public int TCRC;

    //ORIGINAL LINE: public byte RandomNum;
    public byte RandomNum;

    public LocalDateTime IssueTime = LocalDateTime.MIN;

    //ORIGINAL LINE: public uint Tid;
    public long Tid;

    //ORIGINAL LINE: public byte TClassNum;
    public byte TClassNum;

    //ORIGINAL LINE: public byte TSubClassNum;
    public byte TSubClassNum;

    public int xErr;

    //ORIGINAL LINE: protected static readonly ushort[] crc_tab = new ushort[] { 0, 49345, 49537, 320, 49921, 960, 640, 49729, 50689, 1728, 1920, 51009, 1280, 50625, 50305, 1088, 52225, 3264, 3456, 52545, 3840, 53185, 52865, 3648, 2560, 51905, 52097, 2880, 51457, 2496, 2176, 51265, 55297, 6336, 6528, 55617, 6912, 56257, 55937, 6720, 7680, 57025, 57217, 8000, 56577, 7616, 7296, 56385, 5120, 54465, 54657, 5440, 55041, 6080, 5760, 54849, 53761, 4800, 4992, 54081, 4352, 53697, 53377, 4160, 61441, 12480, 12672, 61761, 13056, 62401, 62081, 12864, 13824, 63169, 63361, 14144, 62721, 13760, 13440, 62529, 15360, 64705, 64897, 15680, 65281, 16320, 16000, 65089, 64001, 15040, 15232, 64321, 14592, 63937, 63617, 14400, 10240, 59585, 59777, 10560, 60161, 11200, 10880, 59969, 60929, 11968, 12160, 61249, 11520, 60865, 60545, 11328, 58369, 9408, 9600, 58689, 9984, 59329, 59009, 9792, 8704, 58049, 58241, 9024, 57601, 8640, 8320, 57409, 40961, 24768, 24960, 41281, 25344, 41921, 41601, 25152, 26112, 42689, 42881, 26432, 42241, 26048, 25728, 42049, 27648, 44225, 44417, 27968, 44801, 28608, 28288, 44609, 43521, 27328, 27520, 43841, 26880, 43457, 43137, 26688, 30720, 47297, 47489, 31040, 47873, 31680, 31360, 47681, 48641, 32448, 32640, 48961, 32000, 48577, 48257, 31808, 46081, 29888, 30080, 46401, 30464, 47041, 46721, 30272, 29184, 45761, 45953, 29504, 45313, 29120, 28800, 45121, 20480, 37057, 37249, 20800, 37633, 21440, 21120, 37441, 38401, 22208, 22400, 38721, 21760, 38337, 38017, 21568, 39937, 23744, 23936, 40257, 24320, 40897, 40577, 24128, 23040, 39617, 39809, 23360, 39169, 22976, 22656, 38977, 34817, 18624, 18816, 35137, 19200, 35777, 35457, 19008, 19968, 36545, 36737, 20288, 36097, 19904, 19584, 35905, 17408, 33985, 34177, 17728, 34561, 18368, 18048, 34369, 33281, 17088, 17280, 33601, 16640, 33217, 32897, 16448 };
    protected static final short[] crc_tab = new short[]
            {0, (short) 49345, (short) 49537, 320, (short) 49921, 960, 640, (short) 49729, (short) 50689, 1728, 1920, (short) 51009,
                    1280, (short) 50625, (short) 50305, 1088, (short) 52225, 3264, 3456, (short) 52545, 3840, (short) 53185, (short) 52865,
                    3648, 2560, (short) 51905, (short) 52097, 2880, (short) 51457, 2496, 2176, (short) 51265, (short) 55297, 6336, 6528,
                    (short) 55617, 6912, (short) 56257, (short) 55937, 6720, 7680, (short) 57025, (short) 57217, 8000, (short) 56577,
                    7616, 7296, (short) 56385, 5120, (short) 54465, (short) 54657, 5440, (short) 55041, 6080, 5760, (short) 54849,
                    (short) 53761, 4800, 4992, (short) 54081, 4352, (short) 53697, (short) 53377, 4160, (short) 61441, 12480, 12672,
                    (short) 61761, 13056, (short) 62401, (short) 62081, 12864, 13824, (short) 63169, (short) 63361, 14144, (short) 62721,
                    13760, 13440, (short) 62529, 15360, (short) 64705, (short) 64897, 15680, (short) 65281, 16320, 16000, (short) 65089,
                    (short) 64001, 15040, 15232, (short) 64321, 14592, (short) 63937, (short) 63617, 14400, 10240, (short) 59585,
                    (short) 59777, 10560, (short) 60161, 11200, 10880, (short) 59969, (short) 60929, 11968, 12160, (short) 61249,
                    11520, (short) 60865, (short) 60545, 11328, (short) 58369, 9408, 9600, (short) 58689, 9984, (short) 59329, (short) 59009,
                    9792, 8704, (short) 58049, (short) 58241, 9024, (short) 57601, 8640, 8320, (short) 57409, (short) 40961, 24768, 24960,
                    (short) 41281, 25344, (short) 41921, (short) 41601, 25152, 26112, (short) 42689, (short) 42881, 26432, (short) 42241,
                    26048, 25728, (short) 42049, 27648, (short) 44225, (short) 44417, 27968, (short) 44801, 28608, 28288, (short) 44609,
                    (short) 43521, 27328, 27520, (short) 43841, 26880, (short) 43457, (short) 43137, 26688, 30720, (short) 47297, (short) 47489,
                    31040, (short) 47873, 31680, 31360, (short) 47681, (short) 48641, 32448, 32640, (short) 48961, 32000, (short) 48577, (
                    short) 48257, 31808, (short) 46081, 29888, 30080, (short) 46401, 30464, (short) 47041, (short) 46721, 30272,
                    29184, (short) 45761, (short) 45953, 29504, (short) 45313, 29120, 28800, (short) 45121, 20480, (short) 37057, (short) 37249,
                    20800, (short) 37633, 21440, 21120, (short) 37441, (short) 38401, 22208, 22400, (short) 38721, 21760, (short) 38337,
                    (short) 38017, 21568, (short) 39937, 23744, 23936, (short) 40257, 24320, (short) 40897, (short) 40577, 24128, 23040,
                    (short) 39617, (short) 39809, 23360, (short) 39169, 22976, 22656, (short) 38977, (short) 34817, 18624, 18816, (short) 35137,
                    19200, (short) 35777, (short) 35457, 19008, 19968, (short) 36545, (short) 36737, 20288, (short) 36097, 19904, 19584,
                    (short) 35905, 17408, (short) 33985, (short) 34177, 17728, (short) 34561, 18368, 18048, (short) 34369, (short) 33281,
                    17088, 17280, (short) 33601, 16640, (short) 33217, (short) 32897, 16448};

    public boolean testMode;

    //ORIGINAL LINE: protected static readonly byte[] SubTable1 = new byte[] { 12, 6, 2, 7, 13, 9, 5, 4, 1, 10, 14, 8, 0, 3, 15, 11 };
    protected static final byte[] SubTable1 = new byte[]{12, 6, 2, 7, 13, 9, 5, 4, 1, 10, 14, 8, 0, 3, 15, 11};
    //ORIGINAL LINE: protected static readonly byte[] testSubTable1 = new byte[] { 12, 10, 8, 4, 3, 15, 0, 2, 14, 1, 5, 13, 6, 9, 7, 11 };
    protected static final byte[] testSubTable1 = new byte[]{12, 10, 8, 4, 3, 15, 0, 2, 14, 1, 5, 13, 6, 9, 7, 11};

    //ORIGINAL LINE: protected static readonly byte[] SubTable2 = new byte[] { 9, 11, 6, 5, 12, 7, 14, 2, 13, 3, 1, 15, 4, 8, 0, 10 };
    protected static final byte[] SubTable2 = new byte[]{9, 11, 6, 5, 12, 7, 14, 2, 13, 3, 1, 15, 4, 8, 0, 10};
    //ORIGINAL LINE: protected static readonly byte[] testSubTable2 = new byte[] { 6, 9, 7, 4, 3, 10, 12, 14, 2, 13, 1, 15, 0, 11, 8, 5 };
    protected static final byte[] testSubTable2 = new byte[]{6, 9, 7, 4, 3, 10, 12, 14, 2, 13, 1, 15, 0, 11, 8, 5};

    //ORIGINAL LINE: protected static readonly byte[] SubETable1 = new byte[] { 14, 10, 7, 9, 12, 3, 2, 5, 13, 0, 15, 1, 4, 8, 6, 11 };
    protected static final byte[] SubETable1 = new byte[]{14, 10, 7, 9, 12, 3, 2, 5, 13, 0, 15, 1, 4, 8, 6, 11};
    //ORIGINAL LINE: protected static readonly byte[] testSubETable1 = new byte[] { 12, 10, 8, 4, 3, 15, 0, 2, 14, 1, 5, 13, 6, 9, 7, 11 };
    protected static final byte[] testSubETable1 = new byte[]{12, 10, 8, 4, 3, 15, 0, 2, 14, 1, 5, 13, 6, 9, 7, 11};

    //ORIGINAL LINE: protected static readonly byte[] SubETable2 = new byte[] { 12, 8, 2, 13, 7, 6, 1, 3, 11, 5, 9, 15, 0, 4, 10, 14 };
    protected static final byte[] SubETable2 = new byte[]{12, 8, 2, 13, 7, 6, 1, 3, 11, 5, 9, 15, 0, 4, 10, 14};
    //ORIGINAL LINE: protected static readonly byte[] testSubETable2 = new byte[] { 6, 9, 7, 4, 3, 10, 12, 14, 2, 13, 1, 15, 0, 11, 8, 5 };
    protected static final byte[] testSubETable2 = new byte[]{6, 9, 7, 4, 3, 10, 12, 14, 2, 13, 1, 15, 0, 11, 8, 5};

    //ORIGINAL LINE: protected static readonly byte[] PETable = new byte[] { 55, 42, 10, 18, 24, 21, 44, 35, 2, 22, 56, 43, 27, 58, 9, 50, 6, 36, 12, 61, 37, 38, 53, 16, 62, 3, 7, 4, 32, 20, 63, 25, 51, 52, 54, 33, 49, 19, 46, 29, 48, 31, 23, 30, 41, 28, 13, 5, 40, 60, 39, 11, 15, 17, 1, 0, 57, 34, 59, 8, 47, 14, 45, 26 };
    protected static final byte[] PETable = new byte[]{55, 42, 10, 18, 24, 21, 44, 35, 2, 22, 56, 43, 27, 58, 9, 50, 6, 36, 12, 61, 37, 38, 53, 16, 62, 3, 7, 4, 32, 20, 63, 25, 51, 52, 54, 33, 49, 19, 46, 29, 48, 31, 23, 30, 41, 28, 13, 5, 40, 60, 39, 11, 15, 17, 1, 0, 57, 34, 59, 8, 47, 14, 45, 26};
    //ORIGINAL LINE: protected static readonly byte[] testPETable = new byte[] { 29, 27, 34, 9, 16, 62, 55, 2, 40, 49, 38, 25, 33, 61, 30, 23, 1, 41, 21, 57, 42, 15, 5, 58, 19, 53, 22, 17, 48, 28, 24, 39, 3, 60, 36, 14, 11, 52, 54, 12, 31, 51, 10, 26, 0, 45, 37, 43, 44, 6, 59, 4, 7, 35, 56, 50, 13, 18, 32, 47, 46, 63, 20, 8 };
    protected static final byte[] testPETable = new byte[]{29, 27, 34, 9, 16, 62, 55, 2, 40, 49, 38, 25, 33, 61, 30, 23, 1, 41, 21, 57, 42, 15, 5, 58, 19, 53, 22, 17, 48, 28, 24, 39, 3, 60, 36, 14, 11, 52, 54, 12, 31, 51, 10, 26, 0, 45, 37, 43, 44, 6, 59, 4, 7, 35, 56, 50, 13, 18, 32, 47, 46, 63, 20, 8};

    //ORIGINAL LINE: protected static readonly byte[] PDTable = new byte[] { 55, 54, 8, 25, 27, 47, 16, 26, 59, 14, 2, 51, 18, 46, 61, 52, 23, 53, 3, 37, 29, 5, 9, 42, 4, 31, 63, 12, 45, 39, 43, 41, 28, 35, 57, 7, 17, 20, 21, 50, 48, 44, 1, 11, 6, 62, 38, 60, 40, 36, 15, 32, 33, 22, 34, 0, 10, 56, 13, 58, 49, 19, 24, 30 };
    protected static final byte[] PDTable = new byte[]{55, 54, 8, 25, 27, 47, 16, 26, 59, 14, 2, 51, 18, 46, 61, 52, 23, 53, 3, 37, 29, 5, 9, 42, 4, 31, 63, 12, 45, 39, 43, 41, 28, 35, 57, 7, 17, 20, 21, 50, 48, 44, 1, 11, 6, 62, 38, 60, 40, 36, 15, 32, 33, 22, 34, 0, 10, 56, 13, 58, 49, 19, 24, 30};
    //ORIGINAL LINE: protected static readonly byte[] testPDTable = new byte[] { 44, 16, 7, 32, 51, 22, 49, 52, 63, 3, 42, 36, 39, 56, 35, 21, 4, 27, 57, 24, 62, 18, 26, 15, 30, 11, 43, 1, 29, 0, 14, 40, 58, 12, 2, 53, 34, 46, 10, 31, 8, 17, 20, 47, 48, 45, 60, 59, 28, 9, 55, 41, 37, 25, 38, 6, 54, 19, 23, 50, 33, 13, 5, 61 };
    protected static final byte[] testPDTable = new byte[]{44, 16, 7, 32, 51, 22, 49, 52, 63, 3, 42, 36, 39, 56, 35, 21, 4, 27, 57, 24, 62, 18, 26, 15, 30, 11, 43, 1, 29, 0, 14, 40, 58, 12, 2, 53, 34, 46, 10, 31, 8, 17, 20, 47, 48, 45, 60, 59, 28, 9, 55, 41, 37, 25, 38, 6, 54, 19, 23, 50, 33, 13, 5, 61};

    //ORIGINAL LINE: protected static readonly byte[] binary = new byte[] { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1 };
    protected static final byte[] binary = new byte[]{0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1};

    //===============================================================================================================================
    BaseToken() {
        this.xErr = -1;
        this.RandomNum = this.ToRandom();
        this.IssueTime = LocalDateTime.now();
        this.Tid = this.ToTID(this.IssueTime);
    }

    BaseToken(boolean mode) {
        this.testMode = mode;
        this.xErr = -1;
        this.RandomNum = this.ToRandom();
        this.IssueTime = LocalDateTime.now();
        this.Tid = this.ToTID(this.IssueTime);
    }

    BaseToken(WorkType wt, boolean mode) {
        this.SetWorkType(wt);
        this.testMode = mode;
        this.xErr = -1;
        this.RandomNum = this.ToRandom();
        this.IssueTime = LocalDateTime.now();
        this.Tid = this.ToTID(this.IssueTime);
    }

    //------------------------------------------------------------------------------------------------------------------
    protected void EToByteTokens()
    {
    }

    //ORIGINAL LINE: protected byte ToRandom()
    private byte ToRandom()
    {
        Random rd = new Random();
        //ORIGINAL LINE: return (byte)rd.Next(16);
        return (byte)rd.nextInt(16);
    }

    public final void SetWorkType(WorkType wt) {
        this.workType = wt;
    }

    //ORIGINAL LINE: protected uint ToTID(DateTime dt)
    public final long ToTID(LocalDateTime dt) {
        LocalDateTime zerodt = LocalDateTime.of(2014, 1, 1, 0, 0, 0);
        //ORIGINAL LINE: return (uint)(dt - zerodt).TotalMinutes;
        // 获得两个时间之间的相差值
//        Duration dur = Duration.between(dt, zerodt);
        Duration dur = Duration.between(zerodt, dt);
        //两个时间差的分钟数
        return dur.toMinutes();
    }

    public final void TransferKey(String inkey) {
        if (inkey.length() < 8) {
            this.xErr = 0;
            this.IsKey = false;
            return;
        }
        this.IsKey = true;
//        System.out.println("inkey: " + inkey);
        for (int i = 0; i < 8; i++) {
            //ORIGINAL LINE: this.ByteKey[i] = byte.Parse(inkey.Substring(2 * i, 2), NumberStyles.HexNumber);
            this.ByteKey[i] = (byte)(Integer.valueOf(inkey.substring(2 * i, 2 * i + 2), 16) & 0xFF);
//            System.out.println(String.format(" --- %02X", this.ByteKey[i]));
        }
    }

    //ORIGINAL LINE: public ushort CheckCRC(byte[] ptr)
    public int CheckCRC(byte[] ptr) {
        //ORIGINAL LINE: ushort crc = ushort.MaxValue;
        int crc = 0xFFFF;
        //ORIGINAL LINE: ushort tmp;
        int tmp;
        //ORIGINAL LINE: for (byte i = 0; i < 7; i += 1)
        for (byte i = 0; i < 7; i += 1) {
            //ORIGINAL LINE: ushort short_c = (ushort)(byte.MaxValue & ptr[(int)i]);
            int short_c = (0x00FF & ptr[(int) i]);
            tmp = (crc ^ short_c);
            //ORIGINAL LINE: crc = (ushort)(crc >> 8 ^ (int)BaseToken.crc_tab[(int)(tmp & 255)]);
            crc = (crc >>> 8 ^ (int) BaseToken.crc_tab[(int) (tmp & 255)]) & 0xFFFF;
        }
        tmp = (crc & 65280);
        //ORIGINAL LINE: crc = (ushort)(crc << 8);
        crc = (crc << 8) & 0xFFFF;
        //ORIGINAL LINE: return crc | (ushort)(tmp >> 8);
        return crc | ((tmp >>> 8) & 0xFFFF);
    }

    private void STA(byte[] source, byte[] dest, byte[] inkey, boolean type) {
        //ORIGINAL LINE: byte[] buffer = new byte[64];
        byte[] buffer = new byte[64];
        //ORIGINAL LINE: byte[] buffer2 = new byte[64];
        byte[] buffer2 = new byte[64];
        //ORIGINAL LINE: byte[] kwork = new byte[64];
        byte[] kwork = new byte[64];
        if (type) {
            //ORIGINAL LINE: for (byte i = 0; i < 8; i += 1)
            for (byte i = 0; i < 8; i += 1) {
                //ORIGINAL LINE: inkey[(int)i] = (inkey[(int)i] ^ byte.MaxValue);
                inkey[(int) i] = (byte) ((inkey[(int) i] ^ 0xFF) & 0xFF);
            }
            //ORIGINAL LINE: byte tmp = inkey[0];
            byte tmp = inkey[0];
            //ORIGINAL LINE: byte tmp2 = inkey[1];
            byte tmp2 = inkey[1];
            //ORIGINAL LINE: for (byte i = 1; i < 7; i += 1)
            for (byte i = 1; i < 7; i += 1) {
                //ORIGINAL LINE: inkey[(int)(i - 1)] = (byte)((inkey[(int)i] & 240) >> 4);
                inkey[i - 1] = (byte) (((inkey[(int) i] & 240) >> 4) & 0xFF);
                //ORIGINAL LINE: byte b = i - 1;
                byte b = (byte) (i - 1);
                //ORIGINAL LINE: inkey[(int)b] = (inkey[(int)b] | (byte)((inkey[(int)(i + 1)] & 15) << 4));
                inkey[(int) b] = (byte) (((inkey[(int) b] | (byte) (((inkey[i + 1] & 15) << 4)) & 0xFF)) & 0xFF);
            }
            //ORIGINAL LINE: inkey[6] = (byte)((inkey[7] & 240) >> 4);
            inkey[6] = (byte) (((inkey[7] & 240) >> 4) & 0xFF);
            int num = 6;
            //ORIGINAL LINE: inkey[num] |= (byte)((tmp & 15) << 4);
            inkey[num] |= (byte) (((tmp & 15) << 4) & 0xFF);
            //ORIGINAL LINE: inkey[7] = (byte)((tmp & 240) >> 4);
            inkey[7] = (byte) (((tmp & 240) >> 4) & 0xFF);
            int num2 = 7;
            //ORIGINAL LINE: inkey[num2] |= (byte)((tmp2 & 15) << 4);
            inkey[num2] |= (byte) (((tmp2 & 15) << 4) & 0xFF);
        }

        //ORIGINAL LINE: byte j;
        byte j;
        //ORIGINAL LINE: for (byte i = 0; i < 8; i += 1)
        for (byte i = 0; i < 8; i += 1) {
            //ORIGINAL LINE: byte tmp3 = source[(int)i];
            byte tmp3 = source[(int) i];
            for (j = 0; j < 8; j += 1) {
                if (1 == (tmp3 & 1)) {
                    buffer2[(int) (8 * i + j)] = 1;
                } else {
                    buffer2[(int) (8 * i + j)] = 0;
                }
                //ORIGINAL LINE: tmp3 = (byte)(tmp3 >> 1);
                tmp3 = (byte) ((tmp3 >>> 1) & 0xFF);
            }
        }

        //ORIGINAL LINE: for (byte i = 0; i < 8; i += 1)
        for (byte i = 0; i < 8; i += 1) {
            //ORIGINAL LINE: byte tmp3 = inkey[(int)i];
            byte tmp3 = inkey[(int) i];
            for (j = 0; j < 8; j += 1) {
                if (1 == (tmp3 & 1)) {
                    kwork[(int) (8 * i + j)] = 1;
                } else {
                    kwork[(int) (8 * i + j)] = 0;
                }
                //ORIGINAL LINE: tmp3 = (byte)(tmp3 >> 1);
                tmp3 = (byte) ((tmp3 >>> 1) & 0xFF);
            }
        }

        if (type) {
            //ORIGINAL LINE: for (byte k = 0; k < 16; k += 1)
            for (byte k = 0; k < 16; k += 1) {
                //ORIGINAL LINE: byte tmp3;
                byte tmp3;
                //ORIGINAL LINE: for (byte i = 0; i < 16; i += 1)
                for (byte i = 0; i < 16; i += 1) {
                    tmp3 = 0;
                    for (j = 3; j > 0; j -= 1) {
                        tmp3 = (byte) ((tmp3 + buffer2[(int) (4 * i + j)]) * 2 & 0xFF);
                    }
                    tmp3 += buffer2[(int) (4 * i)];
                    if (1 == kwork[(int) (i * 4 + 3)]) {
                        if (this.testMode) {
                            tmp3 = BaseToken.testSubETable2[(int) tmp3];
                        } else {
                            tmp3 = BaseToken.SubETable2[(int) tmp3];
                        }
                    } else if (this.testMode) {
                        tmp3 = BaseToken.testSubETable1[(int) tmp3];
                    } else {
                        tmp3 = BaseToken.SubETable1[(int) tmp3];
                    }
                    buffer[(int) (i * 4 + 3)] = BaseToken.binary[(int) (tmp3 * 4)];
                    buffer[(int) (i * 4 + 2)] = BaseToken.binary[(int) (1 + tmp3 * 4)];
                    buffer[(int) (i * 4 + 1)] = BaseToken.binary[(int) (2 + tmp3 * 4)];
                    buffer[(int) (i * 4)] = BaseToken.binary[(int) (3 + tmp3 * 4)];
                }
                //ORIGINAL LINE: for (byte i = 0; i < 64; i += 1)
                for (byte i = 0; i < 64; i += 1) {
                    if (this.testMode) {
                        buffer2[(int) BaseToken.testPETable[(int) i]] = buffer[(int) i];
                    } else {
                        buffer2[(int) BaseToken.PETable[(int) i]] = buffer[(int) i];
                    }
                }
                tmp3 = kwork[63];
                //ORIGINAL LINE: for (byte i = 63; i > 0; i -= 1)
                for (byte i = 63; i > 0; i -= 1) {
                    kwork[(int) i] = kwork[(int) (i - 1)];
                }
                kwork[0] = tmp3;
            }
        } else {
            //ORIGINAL LINE: for (byte k = 0; k < 16; k += 1)
            for (byte k = 0; k < 16; k += 1) {
                //ORIGINAL LINE: for (byte i = 0; i < 64; i += 1)
                for (byte i = 0; i < 64; i += 1) {
                    if (this.testMode) {
                        buffer[(int) BaseToken.testPDTable[(int) i]] = buffer2[(int) i];
                    } else {
                        buffer[(int) BaseToken.PDTable[(int) i]] = buffer2[(int) i];
                    }
                }
                //ORIGINAL LINE: byte tmp3;
                byte tmp3;
                //ORIGINAL LINE: for (byte i = 0; i < 16; i += 1)
                for (byte i = 0; i < 16; i += 1) {
                    tmp3 = 0;
                    for (j = 3; j > 0; j -= 1) {
                        tmp3 = (byte) ((tmp3 + buffer[(int) (4 * i + j)]) * 2 & 0xFF);
                    }
                    tmp3 += buffer[(int) (4 * i)];
                    if (1 == kwork[(int) (i * 4)]) {
                        if (this.testMode) {
                            tmp3 = BaseToken.testSubTable2[(int) tmp3];
                        } else {
                            tmp3 = BaseToken.SubTable2[(int) tmp3];
                        }
                    } else if (this.testMode) {
                        tmp3 = BaseToken.testSubTable1[(int) tmp3];
                    } else {
                        tmp3 = BaseToken.SubTable1[(int) tmp3];
                    }
                    buffer2[(int) (i * 4 + 3)] = BaseToken.binary[(int) (tmp3 * 4)];
                    buffer2[(int) (i * 4 + 2)] = BaseToken.binary[(int) (1 + tmp3 * 4)];
                    buffer2[(int) (i * 4 + 1)] = BaseToken.binary[(int) (2 + tmp3 * 4)];
                    buffer2[(int) (i * 4)] = BaseToken.binary[(int) (3 + tmp3 * 4)];
                }
                tmp3 = kwork[0];
                //ORIGINAL LINE: for (byte i = 0; i < 63; i += 1)
                for (byte i = 0; i < 63; i += 1) {
                    kwork[(int) i] = kwork[(int) (i + 1)];
                }
                kwork[63] = tmp3;
            }
        }
        j = 0;
        //ORIGINAL LINE: for (byte i = 0; i < 8; i += 1)
        for (byte i = 0; i < 8; i += 1) {
            dest[(int) i] = 0;
            //ORIGINAL LINE: for (byte k = 7; k > 0; k -= 1)
            for (byte k = 7; k > 0; k -= 1) {
                dest[(int) i] = (byte) ((dest[(int) i] + buffer2[(int) (j + k)]) * 2 & 0xFF);
            }
            //ORIGINAL LINE: byte[] array = dest;
            byte[] array = dest;
            //ORIGINAL LINE: byte b2 = i;
            byte b2 = i;
            array[(int) b2] = (byte) ((array[(int) b2] + buffer2[(int) j]) & 0xFF);
            j += 8;
        }
    }

    // Token: 0x0600000D RID: 13 RVA: 0x00002738 File Offset: 0x00000938
    //ORIGINAL LINE: protected string HexToStrDec(byte[] source, byte num_class)
    public String HexToStrDec(byte[] source, byte num_class) {
        if (num_class > 3) {
            this.xErr = 10;
            return "";
        }
        //ORIGINAL LINE: byte bTmp = (byte)(source[3] >> 3 & 3);
        byte bTmp = (byte) (source[3] >>> 3 & 3);
        int num = 3;
        //ORIGINAL LINE: source[num] &= 231;
        source[num] &= (byte) 231;
        int num2 = 3;
        //ORIGINAL LINE: source[num2] |= (byte)((num_class & 3) << 3);
        source[num2] |= (byte) ((num_class & 3) << 3);
        //ORIGINAL LINE: ulong bToken64 = 0UL;
        long bToken64 = 0;
        for (int i = 0; i < source.length; i++) {
            //ORIGINAL LINE: bToken64 |= (ulong)source[i] << i * 8;
//            long tmp = (0xFFFFFFF)
            bToken64 |= (long) (source[i] & 0xFF) << i * 8;
        }
//        System.out.println("bToken64: " + bToken64 + String.format("  %016X", bToken64));
//        BigInteger bbToken64 = new BigInteger(Long.toUnsignedString(bToken64));
//        System.out.println("bbToken64: " + bbToken64 );
        for (int j = 0; j < 8; j++) {
            this.ByteTokens[9 - (j + 1)] = source[j];
        }
        this.ByteTokens[0] = bTmp;

        BigInteger sIlow = new BigInteger(Long.toUnsignedString(bToken64));
        BigInteger sIhig = new BigInteger(Long.toUnsignedString(bTmp));
        BigInteger sItmp = new BigInteger("18446744073709551616");
//        System.out.println("sIlow: " + sIlow);
//        System.out.println("sIhig: " + sIhig);
//        System.out.println("sItmp: " + sItmp);

//        sItmp *= sIhig;
//        sItmp += sIlow;
        sItmp = sItmp.multiply(sIhig);
        sItmp = sItmp.add(sIlow);
        return sItmp.toString();
    }

    //ORIGINAL LINE: protected string EToken(byte[] source, string inkey)
    public String EToken(byte[] source, String inkey) {
        this.TransferKey(inkey);
        if (source.length < 7) {
            this.xErr = 40;
            return "";
        }
        this.TCRC = this.CheckCRC(source);
        //ORIGINAL LINE: byte[] infoTmp = new byte[8];
        byte[] infoTmp = new byte[8];
        //ORIGINAL LINE: infoTmp[0] = (byte)(this.TCRC & 255);
        infoTmp[0] = (byte) (this.TCRC & 255);
        //ORIGINAL LINE: infoTmp[1] = (byte)(this.TCRC >> 8 & 255);
        infoTmp[1] = (byte) (this.TCRC >> 8 & 255);
        for (int i = 0; i < 6; i++) {
            infoTmp[8 - (i + 1)] = source[i + 1];
        }
        //ORIGINAL LINE: byte[] ekey = new byte[8];
        byte[] ekey = new byte[8];
        if (this.IsKey) {
            for (int j = 0; j < 8; j++) {
                ekey[j] = this.ByteKey[7 - j];
            }
            //ORIGINAL LINE: byte[] tokenTmp = new byte[8];
            byte[] tokenTmp = new byte[8];
            if (this.workType == WorkType.STA) {
                //ORIGINAL LINE: this.STA(infoTmp, ref tokenTmp, ekey, true);
                this.STA(infoTmp, tokenTmp, ekey, true);
            }
            this.StrToken = "00000000000000000000";
            this.StrToken += this.HexToStrDec(tokenTmp, this.TClassNum);
            this.StrToken = this.StrToken.substring(this.StrToken.length() - 20, this.StrToken.length());
            return this.StrToken;
        }
        this.xErr = 0;
        return "";
    }
//---------------------------------------------------------------------------------------------------------------------------------
}